#pragma once
#include "MeshData.h"
#include "Skeleton.h"
#include "BoneWeight.h"
#include "AnimationFrame.h"
#include <glm/mat4x4.hpp>

#include <vector>
#include <memory>

namespace DYGraphics
{
	class _declspec(dllexport) SkinnedMesh
	{
	public:
		SkinnedMesh();
		SkinnedMesh(MeshData* pMeshData, const SkeletonPtr& pSkeleton);
		void Apply();
		void Animation(AnimationFrame* frames);
		void Draw();
		~SkinnedMesh();
	public:
		std::string GetName() const { return mData->name; }

		int GetVertexCount() const { return mData->vertexCnt; }

		int GetIndiceCount() const { return mData->indiceCnt; }

		SkeletonPtr GetSkeleton() const { return mSkeleton; }

		BoneWeight* GetBoneWeight() const { return mData->boneWeights; }

		void SetName(const std::string& name) 
		{
			mData->name = name; 
		}

		void SetVertices(int vertexCnt, Vertex* vertices)
		{
			mData->vertexCnt = vertexCnt;
			mData->vertices = vertices;
		}

		void SetIndices(int indiceCnt, unsigned int* indices)
		{
			mData->indiceCnt = indiceCnt;
			mData->indices = indices;
		}

		void SetMeshData(MeshData* pMeshData)
		{
			mData = pMeshData;
		}

		void SetVertexWeights(BoneWeight* boneWeights)
		{
			mData->boneWeights = boneWeights;
		}

		void SetSkeleton(SkeletonPtr skeleton)
		{
			mSkeleton = skeleton;
		}
	private:
		glm::vec4 Evaluate(glm::vec4 position, int boneIdx, float boneWeight);
	private:
		MeshData* mData;			
		Vertex* mAnimVertices;		// 动画顶点数据
		SkeletonPtr mSkeleton;

		// 顶点数组对象
		unsigned int vao, vbo, ebo;
	};

	typedef std::shared_ptr<SkinnedMesh> SkinnedMeshPtr;
}